package cn.itcast.bos.web.action.system;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ExceptionMapping;
import org.apache.struts2.convention.annotation.ExceptionMappings;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;

import com.itheima.utils.Md5Util;

import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.UserService;
import cn.itcast.bos.web.action.common.BaseAction;

@Controller
@Scope("prototype")
@Namespace("/")//<package namespace extends
@ParentPackage("struts-default")
@Results({
	@Result(name="index",type="redirect",location="/index.jsp"),
	@Result(name="login",location="/login.jsp"),
	@Result(name="list",type="redirect",location="/pages/system/user.jsp"),
	@Result(name="sessionlogin",location="/login.jsp"),
	@Result(name="success",type="redirect",location="/success.jsp"),
	@Result(name="adminsuccess",type="redirect",location="/adminsuccess.jsp")
})
public class UserAction extends BaseAction<User> {
	
	@Autowired
	private UserService userService;
	
	private String checkcode;
	public void setCheckcode(String checkcode) {
		this.checkcode = checkcode;
	}
	
	
	/**
	  * @Description: 基于shiro框架实现用户认证（登陆）
	  * @return
	  * @throws Exception
	  *	  
	 */
	@Action("userAction_login")
	public String login() throws Exception {
		String realCheckcode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
		if(StringUtils.isNotBlank(realCheckcode)){
			if(realCheckcode.equals(checkcode)){
				//开始认证
				//当前用户状态：未认证状态
				Subject subject = SecurityUtils.getSubject();
				if(!subject.isAuthenticated()){   //判断是否认证通过
					//创建认证令牌 
					AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),Md5Util.encode(model.getPassword()));
					//开始认证
					try {
						subject.login(token);
						//认证通过  认证逻辑代码设置主角
						User user = (User) subject.getPrincipal();
						ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
						return "index";
					} catch (Exception e) {
						/*if(e instanceof UnknownAccountException){
							//用户名错误
							this.addActionError("输入账户有误");  //<s:actionerror>  问题：
						}
						if(e instanceof IncorrectCredentialsException){
							
						}*/
						e.printStackTrace();
					}
				} else{
					return "index";
				}
				//加这个else 是因为如果连续两次登录,第二次不会进入认证,所以就永远不会登录成功
				//第一次登陆成功在index.jsp页面地址上手动改回login.jsp页面,就不能登录成功了
			}
		}
		return "login";
	}
	
	
	
	
	/**修改完密码返回登录页面
	 * @return
	 * @throws Exception
	 */
	@Action("userAction_session")
	public String session() throws Exception {
		SecurityUtils.getSubject().logout();
		return "index";
	};
	
	/**  TODO   NIU RUN SHENG 用户密码更改
	 * @return
	 * @throws Exception
	 */
	private String txtNewPass;
	public void setTxtNewPass(String txtNewPass) {
		this.txtNewPass = txtNewPass;
	}
	@Action("userAction_updatePassword")
	public String updatePassword() throws Exception {
		//获取已经登录的用户的名字,密码,判断是否是admin不是就能更改密码,admin不能更改
		
		User user = (User) ServletActionContext.getRequest().getSession().getAttribute("loginUser");
		 String name = user.getUsername();
		 //测试代码
		 System.out.println(name);
		 if(user.getUsername().equals("admin")){
			
			 ServletActionContext.getRequest().getSession().setAttribute("msg", "超级管理员无法更改密码");
			 return "adminsuccess";
		 }else{
			 Integer id = user.getId();
			//测试代码
			 System.out.println(id);
			 //设置提示信息
			 ServletActionContext.getRequest().getSession().setAttribute("msg", "更改密码成功");
			
			 userService.updatePassword(Md5Util.encode(txtNewPass),user.getId());
			
			 //删除session中用户的信息
			
			 ServletActionContext.getRequest().getSession().removeAttribute("loginUser");
			 return "success";
			
		 }
	};
	
	@Action("userAction_logout")
	public String logout() throws Exception {
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "login";
	}
	
	
	private Integer[] roleIds;
	public void setRoleIds(Integer[] roleIds) {
		this.roleIds = roleIds;
	}
	/**
	  * @Description: 1、添加用户记录 2、用户关联角色
	  * @return
	  * @throws Exception
	  *	  
	 */
	@Action("userAction_save")
	public String save() throws Exception {
		userService.save(model,roleIds);
		return "list";
	}
	
	
	/**
	 * @Description: 用户分页查询
	 * @return
	 */
	@Action("userAction_pageQuery")
	public String pageQuery() throws Exception {
		Pageable pageable = new PageRequest(page-1, rows);
		Page<User> page = userService.findAll(pageable);
		this.java2Json(page, new String[]{"roles"});
		return NONE;
	}
}
